﻿using System;
using System.Windows.Forms;
using OpenNETCF.AppSettings;
using Interfaces;

namespace Pozr
{
    // Delegates for global event handling
    public delegate void LogEventHandler(string s);
    public delegate void ModuleLoadedEventHandler(IModule module);
    public delegate void SignalChangedEventHandler(Interfaces.IPositionOriginator module, bool state);

    /// <summary>
    /// Holds a static instance of global program stuff
    /// </summary>
    public class Middleware
    {
        // Global events
        public static event LogEventHandler LogEvent;
        public static event ModuleLoadedEventHandler ModuleLoadedEvent;
        public static event SignalChangedEventHandler SignalChangedEvent;

        // Module handlers
        public static Pozr.PluginServices PluginServices;
        public static Pozr.PositionHandler PositionHandler;

        // Database engine
        public static DatabaseClient Database;

        // Communication interface
        public static Pozr.ServiceWrapper Server;

        // Configuration settings
        public static SettingsWrapper Settings;

        // Reference to the main interface
        public static MainForm mainFrm;

        // Location-based event handler
        public static Pozr.EventEngine EventEngine;

        // Visualization
        public static Map.MapPanel MapDisplay;
        public static Pozr.Markers Markers;

        // Constants
        public static readonly string ConfigurationDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Pozr";
        public static readonly string ApplicationDirectory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);

        // DEBUG LOG WRITER
        public static System.IO.StreamWriter logWriter = new System.IO.StreamWriter(ApplicationDirectory + "\\debug_log.txt");

        public Middleware(MainForm _mainFrm)
        {
            LogEvent += new LogEventHandler(WriteLogToFile);

            Initialize();

            if (_mainFrm != null)
            {
                MapDisplay = new Map.MapPanel(Map.MapPanel.ButtonStateEnum.Show);
                Markers = new Markers();

                mainFrm = _mainFrm;
            }
        }

        public static void Initialize()
        {
            try
            {
                Database = new SqlCeClient();
            }
            catch (Exception ex)
            {
                WriteLogToFile(ex.Message);
                Database = new DummyClient();
            }

            if (!System.IO.Directory.Exists(ConfigurationDirectory))
            {
                System.IO.Directory.CreateDirectory(ConfigurationDirectory);
            }
            Settings = new SettingsWrapper(new SettingsFile(ConfigurationDirectory + "\\settings.xml")); // BN: SettingsFile konstruktor lassú

            Server = new ServiceWrapper();
            PluginServices = new PluginServices();
            PositionHandler = new PositionHandler();
            EventEngine = new EventEngine();
        }

        public static void OnLogEvent(string s)
        {
            if (LogEvent != null)
            {
                LogEvent(s);
            }
        }

        public static void OnModuleLoaded(IModule module)
        {
            if (ModuleLoadedEvent != null)
            {
                ModuleLoadedEvent(module);
            }
        }

        public static void OnSignalChanged(Interfaces.IPositionOriginator module, bool state)
        {
            if (SignalChangedEvent != null)
            {
                SignalChangedEvent(module, state);
            }
        }

        private void InitModules()
        {
            // Load the position originator modules
            PositionHandler.LoadModules();

            // Call the find plugins routine, to search in our Plugins Folder
            PluginServices.LoadModules();

            // Add each plugin to the middleware interface
            foreach (Types.Plugin pluginOn in PluginServices.Plugins)
            {
                OnLogEvent("Plugin loaded: " + pluginOn.Instance.Name);
                OnModuleLoaded(pluginOn.Instance);
            }
        }

        // DEBUG STUFF
        public static void WriteLogToFile(string s)
        {
            Middleware.logWriter.WriteLine("[" + DateTime.Now.ToUniversalTime() + "]" + s);
            Middleware.logWriter.Flush();
        }

        public static void Sleep()
        {
           // mainFrm.Hide();
            mainFrm.Minimize();
            OnLogEvent("Application minimized.");
        }

        public static void Wake()
        {
            mainFrm.Show();
            OnLogEvent("Application restored.");
        }

        /// <summary>
        /// Class that stores the state of an asynchronous request
        /// </summary>
        public class RequestState
        {
       
            /// <summary>
            /// Holds the request
            /// </summary>
            public System.Net.WebRequest Request;
            /// <summary>
            /// Store any data in this
            /// </summary>
            public object Data;
            /// <summary>
            /// Holds the UrlString to match up results (Database lookup, etc).
            /// </summary>
            public string SiteUrl;
            /// <summary>
            /// Constructor of the RequestState class
            /// </summary>
            /// <param name="request">Request</param>
            /// <param name="data">Object Data</param>
            /// <param name="siteUrl">URL string</param>
            public RequestState(System.Net.WebRequest request, object data, string siteUrl)
            {
                this.Request = request;
                this.Data = data;
                this.SiteUrl = siteUrl;
            }
        }
    }
}
